////////////////////////////////////////////////////////////////////////////////////////////////////
/// Copyright (c) 2009 - 2010 RacoonStudios
///
/// Permission is hereby granted, free of charge, to any person obtaining a copy of this
/// software and associated documentation files (the "Software"), to deal in the Software
/// without restriction, including without limitation the rights to use, copy, modify, merge,
/// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
/// to whom the Software is furnished to do so, subject to the following conditions:
///
/// The above copyright notice and this permission notice shall be included in all copies or
/// substantial portions of the Software.
///
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
/// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
/// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
/// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
/// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
/// DEALINGS IN THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////////////////////////

#pragma once
#ifndef line3_h__
#define line3_h__

#include "math/point4.h"
#include "math/vector3.h"
#include "math/scalar.h"

namespace Math
{
	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// \class	line3
	///
	/// \brief	Line 3. 
	///
	/// \author	Markus
	/// \date	05.02.2010
	////////////////////////////////////////////////////////////////////////////////////////////////////
	class line3
	{
	public:

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	 line3()
		///
		/// \brief	Constructor. 
		///
		/// \author	Markus
		/// \date	05.02.2010
		////////////////////////////////////////////////////////////////////////////////////////////////////
		line3();

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	line3(const Math::point4 & p, const Math::vector3 & d)
		///
		/// \brief	Constructor. 
		///
		/// \author	Markus
		/// \date	05.02.2010
		///
		/// \param	[in]	p	The starting point4 of the line3. 
		/// \param	[in]	d	The direction and length of the line3. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		line3(const Math::point4 & p, const Math::vector3 & d);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	line3(const Math::point4 & p1, const Math::point4 & p2)
		///
		/// \brief	Constructor. 
		///
		/// \author	Markus
		/// \date	05.02.2010
		///
		/// \param	[in]	p1	The starting point4 of the line3. 
		/// \param	[in]	p2	The end point4 of the line3. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		line3(const Math::point4 & p1, const Math::point4 & p2);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	line3(const Math::line3 & rhs)
		///
		/// \brief	Constructor. 
		///
		/// \author	Markus
		/// \date	05.02.2010
		///
		/// \param	[in]	rhs	The right hand side object. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		line3(const Math::line3 & rhs);




		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	void operator= (const Math::line3 & rhs)
		///
		/// \brief	Copy operator. 
		///
		/// \author	Markus
		/// \date	05.02.2010
		///
		/// \param	[in]	rhs	The right hand side object. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		void operator = (const Math::line3 & rhs);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	bool operator== (const Math::line3 & rhs) const
		///
		/// \brief	Equality operator. 
		///
		/// \author	Markus
		/// \date	05.02.2010
		///
		/// \param	[in]	rhs	The right hand side object. 
		///
		/// \return	True if both are equal, otherwise false.
		////////////////////////////////////////////////////////////////////////////////////////////////////
		bool operator == (const Math::line3 & rhs) const;

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	bool operator!= (const Math::line3 & rhs) const
		///
		/// \brief	Inequality operator. 
		///
		/// \author	Markus
		/// \date	05.02.2010
		///
		/// \param	[in]	rhs	The right hand side object. 
		///
		/// \return	True if both are inequal, otherwise false.
		////////////////////////////////////////////////////////////////////////////////////////////////////
		bool operator != (const Math::line3 & rhs) const;




		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	scalar length() const
		///
		/// \brief	Returns the length of the line3.
		///
		/// \author	Markus
		/// \date	05.02.2010
		///
		/// \return	The length.
		////////////////////////////////////////////////////////////////////////////////////////////////////
		scalar length() const;

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	scalar lengthsq() const
		///
		/// \brief	Returns the squared length of the line3. 
		///
		/// \author	Markus
		/// \date	05.02.2010
		///
		/// \return	The squared length.
		////////////////////////////////////////////////////////////////////////////////////////////////////
		scalar lengthsq() const;

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	scalar distance(const Math::point4 & p) const
		///
		/// \brief	Computes and return the distance of the line3 and the specified point4.
		///
		/// \author	Markus
		/// \date	05.02.2010
		///
		/// \param	[in]	p	The point4. 
		///
		/// \return	The distance between line3 and point4.
		////////////////////////////////////////////////////////////////////////////////////////////////////
		scalar distance(const Math::point4 & p) const;




		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	void set(const Math::point4 & p, const Math::vector3 & d)
		///
		/// \brief	Sets the starting point4 and the direction and length of the line3.
		///
		/// \author	Markus
		/// \date	05.02.2010
		///
		/// \param	[in]	p	The starting point4 of the line3. 
		/// \param	[in]	d	The direction and length of the line3. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		void set(const Math::point4 & p, const Math::vector3 & d);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	void set(const Math::point4 & p1, const Math::point4 & p2)
		///
		/// \brief	Sets the starting and end point4 of the line3.
		///
		/// \author	Markus
		/// \date	05.02.2010
		///
		/// \param	[in]	p1	The starting point4 of the line3. 
		/// \param	[in]	p2	The end point4 of the line3. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		void set(const Math::point4 & p1, const Math::point4 & p2);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	const Math::point4 & getstart() const
		///
		/// \brief	Returns the starting point4 of the line3.
		///
		/// \author	Markus
		/// \date	05.02.2010
		///
		/// \return	The starting point4.
		////////////////////////////////////////////////////////////////////////////////////////////////////
		const Math::point4 & getstart() const;

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	Math::point4 getend() const
		///
		/// \brief	Returns the end point4 of the line3. 
		///
		/// \author	Markus
		/// \date	05.02.2010
		///
		/// \return	The end point4.
		////////////////////////////////////////////////////////////////////////////////////////////////////
		Math::point4 getend() const;




		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	bool intersectline(const Math::line3 & l) const
		///
		/// \brief	Computes and return if both lines are intersecting.
		///
		/// \author	Markus
		/// \date	05.02.2010
		///
		/// \param	[in]	l	The line3. 
		///
		/// \return	True if both are intersection, otherwise false.
		////////////////////////////////////////////////////////////////////////////////////////////////////
		bool intersectline(const Math::line3 & l) const;

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	bool intersectline(const Math::point4 & p) const
		///
		/// \brief	Computes and return if the line3 and the specified point4 are
		//			intersecting.
		///
		/// \author	Markus
		/// \date	05.02.2010
		///
		/// \param	[in]	p	The point4. 
		///
		/// \return	True if both are intersecting, otherwise false.
		////////////////////////////////////////////////////////////////////////////////////////////////////
		bool intersectline(const Math::point4 & p) const;

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	scalar getclosestpoint_t(const Math::point4 & p) const
		///
		/// \brief	Returns the scalar of the closest point3 to the specified one.
		///
		/// \author	Markus
		/// \date	05.02.2010
		///
		/// \param	[in]	p	The point4. 
		///
		/// \return	The closest point on the line3 as scalar.
		////////////////////////////////////////////////////////////////////////////////////////////////////
		scalar getclosestpoint_t(const Math::point4 & p) const;

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	Math::point4 getclosestpoint(const Math::point4 & p) const
		///
		/// \brief	Returns the closest point4 on the line3 to the specified one.
		///
		/// \author	Markus
		/// \date	05.02.2010
		///
		/// \param	[in]	p	The point4. 
		///
		/// \return	The closest point4 on the line3.
		////////////////////////////////////////////////////////////////////////////////////////////////////
		Math::point4 getclosestpoint(const Math::point4 & p) const;

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	Math::point4 getpointat(scalar t) const
		///
		/// \brief	Returns the point4 at the specified scalar on the line3.
		///
		/// \author	Markus
		/// \date	05.02.2010
		///
		/// \param	[in]	t	The scalar. 
		///
		/// \return	The point4 of the specified scalar.
		////////////////////////////////////////////////////////////////////////////////////////////////////
		Math::point4 getpointat(scalar t) const;

	protected:

		Math::point4 m_point;
		Math::vector3 m_direction;

	private:

	};

}

#endif // line3_h__